package com.xj.context;

import com.xj.annotations.XJBean;
import com.xj.annotations.XJBeanScan;

import java.io.File;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class XJApplicationContext {

    /**
     * 因为不知道传递什么类进来，此处采取Class接收
     */
    private Class aClass;

    public XJApplicationContext(Class aClass) throws ClassNotFoundException {
        this.aClass = aClass;

        // 针对容器而言，需要保证一个可扩展性 ---- 可支持随机应变
        // 所以，在配置扫描类中，定义了一个当前的路径value属性值
        // 此时就可以派上大用处

        // 1、判断传递至容器中的Class字节码文件的类上是否存在指定的注解
        if (aClass.isAnnotationPresent(XJBeanScan.class)) {
            // 2、如果存在这个指定的注解，那么就需要进行解析
            // 此处需要获取到这个配置类中的配置信息，所以需要先拿到这个注解对象
            Annotation annotation = aClass.getAnnotation(XJBeanScan.class);
            // 每个注解都是当前这个注解的子类，所以需要转换为指定的子类
            XJBeanScan xjBeanScan = (XJBeanScan) annotation;
            // 获取这个配置类中，已配置的值
            String path = xjBeanScan.value();

            // 3、通过类加载器，加载指定包下的类
            ClassLoader classLoader = XJApplicationContext.class.getClassLoader();
            // 注意：此处需要传递一个目录！！！
            path = path.replaceAll("\\.", "/");

            URL resource = classLoader.getResource(path);
            //System.out.println(resource);
            // 此时，则可以根据这个 url 获取到文件对象
            File file = new File(resource.getFile());
            // 遍历文件对象，判断当前文件对象是否是文件夹
            if (file.isDirectory()) {
                System.out.println(file); // F:\xj_spring\target\classes\com\xj
                // 既然是文件夹，那么就可以拿到当前文件夹下的所有文件
                //File[] files = file.listFiles();
                List<File> files = getFiles(file, new ArrayList<File>());
                // 判断每个文件，主要是过滤文件格式
                for (File file1 : files) {
                    // 获取当前文件的别名信息
                    String absolutePath = file1.getAbsolutePath();
                    // 如果当前文件是 class 文件，则继续处理
                    if(absolutePath.endsWith(".class")){
                        // 但是一个包下有很多类，有些类是需要交给容器进行管理和维护的，有些则不需要，所以还需要判断包下的类上是否存在bean的注解
                        // 通过类加载器加载这个class文件
                        String classNamePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
                        String className = classNamePath.replace("\\",".");
                        System.out.println(className);
                        Class<?> aClass1 = classLoader.loadClass(className);
                        // 如果加载的这个类上存在指定的bean类注解，则表示是需要找的那个类
                        if(aClass1.isAnnotationPresent(XJBean.class)){

                        }
                    }
                }
            }

        }
    }

    /**
     * 通过File对象获取其中的所有文件集合
     * @param file 待遍历的文件/文件夹
     * @param fileList 保存的集合数
     * @return
     */
    private static List<File> getFiles(File file,List<File> fileList){
        File[] files = file.listFiles();
        for (File file1 : files) {
            if(file1.isDirectory()){
                getFiles(file1.getAbsoluteFile(),fileList);
            }else{
                fileList.add(file1);
            }
        }
        return fileList;
    }

    /**
     * bean的创建方法
     * @param beanName
     * @return
     */
    public Object getBean(String beanName) {

        return null;
    }
}
